// 
//   Copyright © 2009 Jiří Zárevúcky <zarevucky.jiri@gmail.com>
//  
//   This program is free software: you can redistribute it and/or modify
//   it under the terms of the GNU Affero General Public License as
//   published by the Free Software Foundation, either version 3 of the
//   License, or (at your option) any later version.
//  
//   This program is distributed in the hope that it will be useful,
//   but WITHOUT ANY WARRANTY; without even the implied warranty of
//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//   GNU Affero General Public License for more details.
//  
//   You should have received a copy of the GNU Affero General Public License
//   along with this program.  If not, see <http://www.gnu.org/licenses/>.
//  
//  

using System;

using Galaxium.Protocol.Xmpp.Library.Xml;
using Galaxium.Protocol.Xmpp.Library.Core;

namespace Galaxium.Protocol.Xmpp.Library.Extensions
{	
	public static class XmlStorage
	{		
		public static void StoreData (CoreStream stream, Element elm, int timeout)
		{
			if (stream == null)
				throw new ArgumentNullException ("stream");
			if (elm.Namespace == null)
				throw new ArgumentException ("elm doesn't have a namespace");

			var priv = new Element ("query", Namespaces.XmlStorage);
			priv.AppendChild (elm);
			var iq = new Iq (IqType.Set);
			iq.AppendChild (priv);
			
			try {
				stream.SendQuery (iq, timeout);
			}
			catch (QueryException e) {
				if (e.Condition == "not-acceptable")
					throw new ArgumentException ("elm has unacceptable namespace");
				if (e.Condition == "service-unavailable")
					throw new NotSupportedException ();
			
				throw; // unexpected query error
			}
		}
		
		public static Element RetrieveData (CoreStream stream, string name,
		                                    string ns, int timeout)
		{
			if (stream == null)
				throw new ArgumentNullException ("stream");
			if (String.IsNullOrEmpty (name))
				throw new ArgumentNullException ("name");
			if (String.IsNullOrEmpty (ns))
				throw new ArgumentNullException ("ns");
					
			var priv = new Element ("query", Namespaces.XmlStorage);
			priv.AppendChild (new Element (name, ns));
			var iq = new Iq (IqType.Get);
			iq.AppendChild (priv);
			
			try {
				var result = stream.SendQuery (iq, timeout);
				return result.FirstChild ("query", Namespaces.XmlStorage)
					.FirstChild ("storage", Namespaces.Bookmarks);
			}
			catch (QueryException e) {
				if (e.Condition == "not-acceptable")
					throw new ArgumentException ("unaceptable namespace");
				if (e.Condition == "service-unavailable")
					throw new NotSupportedException ();
			
				throw; // unexpected query error
			}
		}
	}
}
